package nature.nano.classinfo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import nature.nano.component.Strings;
import nature.nano.iface.enumer.EnumStringCallback;

public class ClassInfoLib {

	private Map<String, ArrayList<String>> shortNameInfos = new HashMap<String, ArrayList<String>>();
	
	private ClassInfoLib() {
		ClassScanner.scan(
			new EnumStringCallback() {
				public void onRead(String clazz) {
					add(clazz);
				}
			});
	}
	
	public int enumClass(EnumStringCallback callback) {
		for (String name : shortNameInfos.keySet()) {
			callback.onRead(name);
		}
		return shortNameInfos.size();
	}
	
	public Object newInstance(String clazz) {
		String shortName = getShortName(clazz);
		ArrayList<String> longNames = shortNameInfos.get(shortName);
		if (longNames == null) {
			return null;
		}
		
		int matchCount = 0;
		String matchClazz = null;
		for (String longName : longNames) {
			if (longName.endsWith(clazz)) {
				matchClazz = longName;
				matchCount++;
			}
		}
		
		if (matchCount != 1) {
			return null;
		}
		
		try {
			return Class.forName(matchClazz).newInstance();
		} catch (Exception e) {
			return null;
		}
	}
	
	
	private void add(String clazz) {
		String shortName = getShortName(clazz);
		if (shortName.indexOf(Strings.dollar) >= 0) {
			return;
		}
		ArrayList<String> longNames = shortNameInfos.get(shortName);
		if (longNames == null) {
			longNames = new ArrayList<String>();
			shortNameInfos.put(shortName, longNames);
		}
		longNames.add(clazz);
	}
	
	private String getShortName(String clazz) {
		int i = clazz.lastIndexOf(Strings.period);
		i = (i >= 0) ? i + 1 : 0;
		return clazz.substring(i, clazz.length());
	}
	
	private static ClassInfoLib instance = new ClassInfoLib();
	
	public static ClassInfoLib instance() {
		return instance;
	}
	
	public static void main(String[] args) {
		ClassInfoLib lib = new ClassInfoLib();
		Object object = lib.newInstance("component.SimpleSlotBoard");
		System.out.println(object);
	}
	
}
